package com.well.rpc.job;

import com.well.rpc.WellRpcException;
import com.well.rpc.config.ClientDataConfig;
import com.well.rpc.handler.ClientEventHandler;
import com.well.rpc.handler.ClientHandler;
import com.well.rpc.model.DoJobHandlerModel;
import com.well.rpc.model.DoJobResponseModel;
import com.well.rpc.model.EventType;
import com.well.rpc.model.JobHandlerModel;
import org.springframework.scheduling.support.CronTrigger;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.well.rpc.model.CodeInfo.CRON_EXPRESSION_ERROR;

/**
 * <p>
 * 处理任务
 * </p>
 *
 * @author weedo
 * @since 2022/8/6
 */
public class JobHandler {

    private static final int SUCCESS = 0;
    private static final int FAIL = 1;

    /**
     *  检查cron表达式
     * @param jobName
     * @param cronExpression cron表达式
     */
    public static void checkCronExpression(String jobName, String cronExpression) {
        try {
             new CronTrigger(cronExpression);
        } catch (Exception e) {
            throw new WellRpcException(CRON_EXPRESSION_ERROR.getCode(),
                    String.format(CRON_EXPRESSION_ERROR.getMsg(), jobName, e.getMessage()));
        }
    }

    /**
     * @return 返回所有的JobHandler信息
     */
    public static List<JobHandlerModel> getAllJobHandlerModel() {
        List<JobHandlerModel> models = new ArrayList<>();
        Map<String, WellJobHandler> jobHandlerMap = ClientDataConfig.getJobHandlerMap();
        for (Map.Entry<String, WellJobHandler> entry : jobHandlerMap.entrySet()) {
            JobHandlerModel model = new JobHandlerModel();
            model.setJobName(entry.getKey());
            model.setCron( entry.getValue().cronTrigger());
            models.add(model);
        }
        return models;
    }


    /**
     * 执行任务
     * @param doJobHandlerModel 任务名称
     * @param context
     */
    public static void doJob(DoJobHandlerModel doJobHandlerModel, WellJobContext context) {
        WellJobHandler jobHandler = ClientDataConfig.getJobHandler(doJobHandlerModel.getJobName());
        DoJobResponseModel doJobResponseModel = new DoJobResponseModel();
        doJobResponseModel.setJobId(doJobHandlerModel.getJobId());
        if (jobHandler == null) {
            // 没有任务说明，告诉serve这个事情
            doJobResponseModel.setResult(FAIL);
            doJobHandlerModel.setJobName("Not found jobName.");
            ClientHandler.writeToServer(EventType.DO_JOB_RESPONSE, doJobResponseModel);
            return;
        }

        try {
            jobHandler.handleJob(context);
        } catch (Exception e) {
            e.printStackTrace();
            try {
                jobHandler.handleExceptionCaught();
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            doJobResponseModel.setResult(FAIL);
            doJobResponseModel.setMsg(e.getMessage());
            ClientHandler.writeToServer(EventType.DO_JOB_RESPONSE, doJobResponseModel);
            return;
        }
        doJobResponseModel.setResult(SUCCESS);
        ClientHandler.writeToServer(EventType.DO_JOB_RESPONSE, doJobResponseModel);
    }
}
